﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;
using System.IO;
using ModEngine;
using Iris.Engine;
using System.Security.Cryptography;
using System.Threading.Tasks;
using System.Globalization;

namespace Iris.ImageProcess
{

    /// <summary>
    /// Consomme les evenements : BeginLoadDataSourceEvent
    /// declenche les evenements : LoadDataSource, EndLoadDataSource, LoadDataSourceFailed, RaiseException
    /// </summary>
    public class ImageLoader : IModule
    {
        private volatile bool DisposeFlag = false;
        private Thread threadScan;
        
        public string getDescriptionModule()
        {
            return "Thread de chargement des d'images via la librairie FreeImageNET";
        }

        public string getNameModule()
        {
            return "FreeImageLoader";
        }

        public string getVersion()
        {
            return "1.0";
        }

        public ImageLoader()
        {
            SortCore.singleton.BeginLoadDataSourceEvent += on_BeginLoadDataSourceEvent;
        }

        public void Dispose()
        {
            try
            {
                StopThreadScan();
            }
            catch (Exception) { }
        }

        private void StopThreadScan()
        {
            if (threadScan != null && threadScan.IsAlive)
            {
                DisposeFlag = true;
                int i = 0;
                // TODO test Thread.Join()  : doesn't work ?!!
                while (DisposeFlag && i < 20)
                {
                    Thread.Sleep(200);
                    i++;
                }

                DisposeFlag = false;
            }
        }
         
           
        public void on_BeginLoadDataSourceEvent(string path)
        {
            StopThreadScan();
            threadScan = new Thread(runScan);
            threadScan.IsBackground = true;
            threadScan.Priority = ThreadPriority.Normal;
            threadScan.Start(path);
        }

        public void runScan(object path)
        {

            DirectoryInfo folder = new DirectoryInfo((string)path);
            if (folder.Exists)
            {
                List<FileInfo> filesScan = GetFiles(folder, new string[] { ".png", ".nef", ".jpg", ".jpeg", ".tiff" });
    
                int IndexTraitement = 0;
                int TotalTraitement = filesScan.Count;
                foreach (FileInfo file in filesScan)
                {
                    IndexTraitement++;
                    ImageSort image = new ImageSort() { DataSource = file };
                    SortCore.singleton.WaitLoadDataSource(image, IndexTraitement, TotalTraitement);
                    TraiterFichierImage(image);
                    if (DisposeFlag)
                    {
                        DisposeFlag = false;
                        break;
                    }
                }
                DisposeFlag = false;
                SortCore.singleton.EndLoadDataSource();
            }
        }

        private void TraiterFichierImage(ImageSort image)
        {
            try
            {
                image.InitProperties();
                image.thumbail = image.presentation = FreeImageHelper.ReadImage(image.DataSource);
                
                SortCore.singleton.LoadDataSource(image);
            }

            catch (Exception e) {
                SortCore.singleton.RaiseException(e, "TraiterFichierImage");
                SortCore.singleton.LoadDataSourceFailed(image.DataSource);
            }
        }

         
        #region aides

        private static bool inTest(String val, String[] arr)
        {
            foreach (String arrVal in arr)
            {
                if (arrVal == val)
                {
                    return true;
                }
            }
            return false;
        }

        private static List<FileInfo> GetFiles(DirectoryInfo folder, string[] extentions)
        {
            List<FileInfo> filesScan = new List<FileInfo>();

            foreach (FileInfo file in folder.GetFiles())
            {
                if (inTest(file.Extension.ToLower(), extentions))
                {
                    filesScan.Add(file);
                }
            }
            /*
            foreach (DirectoryInfo fold in folder.GetDirectories())
            {
                filesScan.AddRange(GetFiles(fold, extentions));
            }*/
            return filesScan;
        }

        #endregion
    }
}
